package com.xiaobai.common.utils.mp;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.xiaobai.common.utils.tool.AuthUtil;
import com.xiaobai.common.utils.tool.UserInfo;
import jakarta.validation.constraints.NotEmpty;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Validated
public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseEntity> extends ServiceImpl<M, T> implements BaseService<T> {
    public BaseServiceImpl() {
    }

    public boolean save(T entity) {
        this.resolveEntity(entity);
        return super.save(entity);
    }

    public boolean saveBatch(Collection<T> entityList, int batchSize) {
        entityList.forEach(this::resolveEntity);
        return super.saveBatch(entityList, batchSize);
    }

    public boolean updateById(T entity) {
        this.resolveEntity(entity);
        return super.updateById(entity);
    }

    public boolean updateBatchById(Collection<T> entityList, int batchSize) {
        entityList.forEach(this::resolveEntity);
        return super.updateBatchById(entityList, batchSize);
    }

    public boolean saveOrUpdate(T entity) {
        return entity.getId() == null ? this.save(entity) : this.updateById(entity);
    }

    public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
        entityList.forEach(this::resolveEntity);
        return super.saveOrUpdateBatch(entityList, batchSize);
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean deleteLogic(@NotEmpty List<Long> ids) {
        UserInfo user = AuthUtil.getUser();
        List<T> list = new ArrayList<>();
        ids.forEach((id) -> {
            T entity = BeanUtils.instantiateClass(this.currentModelClass());
            if (user != null) {
                entity.setUpdateUser(user.getId());
            }

            entity.setUpdateTime(LocalDateTime.now());
            entity.setId(id);
            list.add(entity);
        });
        return super.updateBatchById(list) && super.removeByIds(ids);
    }


    private void resolveEntity(T entity) {
        try {
            UserInfo user = AuthUtil.getUser();
            LocalDateTime now = LocalDateTime.now();
            if (entity.getId() == null) {
                if (user != null) {
                    entity.setCreateUser(user.getId());
                    entity.setUpdateUser(user.getId());
                }
                entity.setCreateTime(now);
            } else if (user != null) {
                entity.setUpdateUser(user.getId());
            }

            entity.setUpdateTime(now);
            entity.setIsDeleted(0);
        } catch (Throwable var8) {
            throw var8;
        }
    }
}